// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.2 OR LicenseRef-Slint-commercial

// Test that the correct item indices are computed when focusing
// children of sub-components or their roots.

SubComponentWithFocusableChild := Rectangle {
    property <bool> has-focus: input.has-focus;

    callback activate();
    activate => {
        input.focus();
    }

    input := TextInput {
        width: 100%;
        height: 100%;
    }
}

SubComponentWithRootFocusable := TextInput {
    callback activate();
    activate => {
        root.focus();
    }
}

FocusInNestedSubComponent := Rectangle {
    property <bool> has-focus: compo.has-focus;
    callback activate();
    activate => {
        compo.activate();
    }
    compo := SubComponentWithRootFocusable {
    }
}


TestCase := Rectangle {
    width: 400phx;
    height: 400phx;

    callback focus_subcompo1();
    focus_subcompo1 => { input1.activate(); }
    callback focus_subcompo2();
    focus_subcompo2 => { input2.activate(); }
    callback focus_subcompo3();
    focus_subcompo3 => { input3.activate(); }

    input1 := SubComponentWithFocusableChild {
        y: 0phx;
        height: 150phx;
    }

    input2 := SubComponentWithRootFocusable {
        y: 150phx;
        height: 150phx;
    }

    input3 := FocusInNestedSubComponent {
        y: 250px;
        height: 150px;
    }

    property<bool> input1_focused: input1.has_focus;
    property<bool> input2_focused: input2.has_focus;
    property<bool> input3_focused: input3.has_focus;

}

/*
```rust
let instance = TestCase::new().unwrap();
assert!(!instance.get_input1_focused());
assert!(!instance.get_input2_focused());
assert!(!instance.get_input3_focused());

instance.invoke_focus_subcompo1();
assert!(instance.get_input1_focused());
assert!(!instance.get_input2_focused());
assert!(!instance.get_input3_focused());

instance.invoke_focus_subcompo2();
assert!(!instance.get_input1_focused());
assert!(instance.get_input2_focused());
assert!(!instance.get_input3_focused());

instance.invoke_focus_subcompo3();
assert!(!instance.get_input1_focused());
assert!(!instance.get_input2_focused());
assert!(instance.get_input3_focused());
```

```cpp
auto handle = TestCase::create();
const TestCase &instance = *handle;
assert(!instance.get_input1_focused());
assert(!instance.get_input2_focused());
assert(!instance.get_input3_focused());

instance.invoke_focus_subcompo1();
assert(instance.get_input1_focused());
assert(!instance.get_input2_focused());
assert(!instance.get_input3_focused());

instance.invoke_focus_subcompo2();
assert(!instance.get_input1_focused());
assert(instance.get_input2_focused());
assert(!instance.get_input3_focused());

instance.invoke_focus_subcompo3();
assert(!instance.get_input1_focused());
assert(!instance.get_input2_focused());
assert(instance.get_input3_focused());
```

```js
var instance = new slint.TestCase();
assert(!instance.input1_focused);
assert(!instance.input2_focused);
assert(!instance.input3_focused);

instance.focus_subcompo1();
assert(instance.input1_focused);
assert(!instance.input2_focused);
assert(!instance.input3_focused);

instance.focus_subcompo2();
assert(!instance.input1_focused);
assert(instance.input2_focused);
assert(!instance.input3_focused);

instance.focus_subcompo3();
assert(!instance.input1_focused);
assert(!instance.input2_focused);
assert(instance.input3_focused);
```
*/
